/**
 * 
 */
package cl.duocap.refaxion.dao;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import cl.duocap.refaxion.dto.ItemOrdenTrabajoDTO;
import cl.duocap.refaxion.dto.OrdenTrabajoDTO;
import cl.duocap.refaxion.dto.ParametroBusquedaDTO;
import cl.duocap.refaxion.dto.RepuestoDTO;
import cl.duocap.refaxion.dto.ServicioDTO;
import cl.duocap.refaxion.servicios.UsuarioService;
import cl.duocap.refaxion.servicios.VehiculoService;

/**
 * @author rentonx
 * 
 */
public class OrdenTrabajoDAO {

	/**
	 * 
	 */

	private Connection conexion;

	public boolean registroOrdenTrabajoNueva(OrdenTrabajoDTO ordenNueva) {

		try {

			CallableStatement cstmt = conexion
					.prepareCall("{ call paInsRefaxionRegistrarOrdenTrabajo(?,?,?,?,?,?,?,?,?,?,?,?)}");

			int i = 1;

			cstmt.setInt(i++, ordenNueva.getIdOrdenDeTrabajo());
			cstmt.setInt(i++, 0);
			cstmt.setString(i++, ordenNueva.getFechaIngreso());
			cstmt.setString(i++, ordenNueva.getFechaEntrega());
			cstmt.setInt(i++, ordenNueva.getPrecioTotal());
			if (ordenNueva.getIdTipoServicio() == 1) {
				cstmt.setString(i++, "mantencion");
			} else {
				cstmt.setString(i++, "reparacion");
			}
			cstmt.setInt(i++, ordenNueva.getIdPaqueteMantencion());
			cstmt.setInt(i++, ordenNueva.getIdVehiculo());
			cstmt.setInt(i++, ordenNueva.getIdTipoServicio());
			cstmt.setInt(i++, ordenNueva.getIdTaller());
			cstmt.setInt(i++, ordenNueva.getIdUsuario());
			cstmt.setInt(i++, 0);

			cstmt.executeUpdate();
			cstmt.close();

			return true;

		} catch (SQLException ex) {
			throw new RuntimeException(
					"error obtener id maximo Ordenes de Trabajo.", ex);

		} finally {
			try {
				conexion.close();

			} catch (Exception ex) {

			}
			try {

				conexion.close();

			} catch (Exception ex) {

			}

		}

	}
	
	public boolean registroOrdenTrabajoNuevaRepuestosSeleccionados(List<RepuestoDTO> listaRepuestosSelEnGrilla, int idOrdenTrabajoNueva){
		
		try {
			
			
			CallableStatement cstmt = conexion.prepareCall("{ call paInsRefaxionRegistrarOrdenTrabajoRepuestosSeleccionados(?,?,?,?)}");
	
			int i = 1;
			
			for (RepuestoDTO r : listaRepuestosSelEnGrilla) {
				i = 1;
				cstmt.setInt(i++,idOrdenTrabajoNueva);
				cstmt.setInt(i++,r.getIdRepuesto());
				cstmt.setInt(i++,r.getCantidad());
				cstmt.setInt(i++,r.getPrecioRepuesto());

				cstmt.executeUpdate();
				
			}
			cstmt.close();
			return true;
			
			
		 } catch (SQLException ex) {
	         throw new RuntimeException("error: guardar repuestos asociados a una orden de trabajo.",ex);   
	         
	    }finally {
	         try{
	        	 conexion.close();
	        	
	        }catch (Exception ex){
	            
	        }
	        try{
	        	
	            conexion.close();
	            
	        }catch (Exception ex){
	            
	        }
	        
	    }
		
		
	}
	
	public boolean registroOrdenTrabajoNuevaServiciosSeleccionados(List<ServicioDTO> listaServiciosSelEnGrilla, int idOrdenTrabajoNueva){
		
		try {
			
			
			CallableStatement cstmt = conexion.prepareCall("{ call paInsRefaxionRegistrarOrdenTrabajoServiciosSeleccionados(?,?)}");
	
			int i = 1;
			
			for (ServicioDTO r : listaServiciosSelEnGrilla) {
				i = 1;
				cstmt.setInt(i++,idOrdenTrabajoNueva);
				cstmt.setInt(i++,r.getIdServicio());
				
				cstmt.executeUpdate();
				
			}
			cstmt.close();
			return true;
			
			
		 } catch (SQLException ex) {
	         throw new RuntimeException("error: guardar servicios asociados a una orden de trabajo.",ex);   
	         
	    }finally {
	         try{
	        	 conexion.close();
	        	
	        }catch (Exception ex){
	            
	        }
	        try{
	        	
	            conexion.close();
	            
	        }catch (Exception ex){
	            
	        }
	        
	    }
		
		
	}

	public int obtenerIdMaximoOT() {

		ResultSet rset = null;
		OrdenTrabajoDTO idMax = new OrdenTrabajoDTO();

		try {

			CallableStatement cstmt = conexion
					.prepareCall("{ call paConIdMaximoOrdenTrabajo()}");
			rset = cstmt.executeQuery();
			while (rset.next()) {
				idMax.setIdOrdenDeTrabajo((rset.getInt("idMaximoOrdenes")));
			}
			cstmt.close();

		} catch (SQLException ex) {
			throw new RuntimeException(
					"error obtener id maximo Ordenes de Trabajo.", ex);

		} finally {
			try {
				conexion.close();

			} catch (Exception ex) {

			}
			try {

				conexion.close();

			} catch (Exception ex) {

			}

		}
		return idMax.getIdOrdenDeTrabajo();
	}

	public boolean asignarResponsableOT(int idOrdentrabajo, int idUsuario) {

		try {

			CallableStatement cstmt = conexion
					.prepareCall("{ call paUpdRefaxionOrdenTrabajoAsignarResponsable(?,?)}");

			int i = 1;
			cstmt.setInt(i++, idOrdentrabajo);
			cstmt.setInt(i++, idUsuario);
			cstmt.executeUpdate();
			cstmt.close();

		} catch (Exception ex) {
			throw new RuntimeException("Error asignar empleado a OT.", ex);
		} finally {

			try {
				conexion.close();

			} catch (Exception ex) {

			}
			try {
				conexion.close();

			} catch (Exception ex) {
			}
		}
		return true;
	}

	// /////////////////////////////////////////////////////////////////metodo
	// de anulacion 1.0
	public boolean anularOrdenTrabajo(int idOrdentrabajo) {

		try {

			CallableStatement cstmt = conexion
					.prepareCall("{ call paUpdRefaxionOrdenTrabajoAnular(?)}");

			int i = 1;
			cstmt.setInt(i++, idOrdentrabajo);
			cstmt.executeUpdate();
			cstmt.close();

		} catch (Exception ex) {
			throw new RuntimeException("Error Anular OT.", ex);
		} finally {

			try {
				conexion.close();

			} catch (Exception ex) {

			}
			try {
				conexion.close();

			} catch (Exception ex) {
			}
		}
		return true;
	}

	// /////////////////////////////////////////////////////////////////metodo
	// de actualizar estado OT 1.0
	public boolean actualizarEstadoOrdenTrabajo(int idOrdentrabajo,
			int estadoNuevo) {

		try {

			CallableStatement cstmt = conexion
					.prepareCall("{ call paUpdRefaxionOrdenTrabajoActualizarEstado(?,?)}");

			int i = 1;
			cstmt.setInt(i++, idOrdentrabajo);
			cstmt.setInt(i++, estadoNuevo);
			cstmt.executeUpdate();
			cstmt.close();

		} catch (Exception ex) {
			throw new RuntimeException("Error Actualizar Estado OT.", ex);
		} finally {

			try {
				conexion.close();

			} catch (Exception ex) {

			}
			try {
				conexion.close();

			} catch (Exception ex) {
			}
		}
		return true;
	}

	// ////////////////////////////////////////////////////////////////////////////////////////////////////////
	public OrdenTrabajoDTO buscarOrdenTrabajo(int idOrdenTrabajo) {

		ResultSet rset = null;
		OrdenTrabajoDTO ordenBuscada = new OrdenTrabajoDTO();

		try {

			CallableStatement cstmt = conexion
					.prepareCall("{ call paConRefaxionBuscarOrdenTrabajo(?)}");

			int i = 1;
			cstmt.setInt(i++, idOrdenTrabajo);
			rset = cstmt.executeQuery();
			while (rset.next()) {

				ordenBuscada.setIdOrdenDeTrabajo(rset
						.getInt("idOrdenDeTrabajo"));
				ordenBuscada.setResponsable(rset.getInt("responsable"));
				ordenBuscada.setFechaIngreso(rset.getString("fechaIngreso"));
				ordenBuscada.setFechaEntrega(rset.getString("fechaEntrega"));
				ordenBuscada.setPrecioTotal(rset.getInt("precioTotal"));
				ordenBuscada.setDescripcion(rset.getString("descripcion"));
				ordenBuscada.setIdPaqueteMantencion(rset
						.getInt("idPaqueteMantencion"));
				ordenBuscada.setIdVehiculo(rset.getInt("idVehiculo"));
				ordenBuscada.setIdTipoServicio(rset.getInt("idTipoServicio"));
				ordenBuscada.setIdTaller(rset.getInt("idTaller"));
				ordenBuscada.setIdUsuario(rset.getInt("idUsuario"));
				ordenBuscada.setEstado(rset.getInt("estado"));
				// agregar los datos del cliente de la OT
				UsuarioService cliente = new UsuarioService();
				ordenBuscada.setCliente(cliente.cargarUsuarioEditar(rset.getInt("idUsuario")));
				
				//agregar datos del vehiculo de la OT
				VehiculoService vehiculo = new VehiculoService();
				ordenBuscada.setVehiculoOT(vehiculo.buscarVehiculoPorId(rset.getInt("idVehiculo")));
			}
			cstmt.close();

		} catch (SQLException ex) {

			throw new RuntimeException("error traer Orden de Trabajo.", ex);

		} finally {

			try {
				conexion.close();

			} catch (Exception ex) {

			}
			try {
				conexion.close();

			} catch (Exception ex) {
			}

		}

		SimpleDateFormat formatoDelTexto = new SimpleDateFormat("dd-MM-yyyy");
		String strFecha = ordenBuscada.getFechaIngreso();
		Date fecha = null;
		try {

			fecha = formatoDelTexto.parse(strFecha);

		} catch (ParseException ex) {

			ex.printStackTrace();

		}

		ordenBuscada.setFechaIngresoTrans(fecha);

		return ordenBuscada;

	}

	// //////////////////////////////////////////////////////////////////////////////////////////////////
	// realizar busqieda de orden de trabajo para mostrar en bandejaBusquedaOT

	public List<OrdenTrabajoDTO> bandejaBuscarOT(ParametroBusquedaDTO buscaOT) {
		List<OrdenTrabajoDTO> listaResultadoBusquedaOT = new ArrayList<OrdenTrabajoDTO>();
		ResultSet rset = null;
		

		try {

			CallableStatement cstmt = conexion
					.prepareCall("{ call paConRefaxionBandejaBusquedaOT(?,?,?,?,?,?,?)}");

			int i = 1;
			cstmt.setInt(i++, buscaOT.getIdOrdenTrabajo());
			cstmt.setString(i++, buscaOT.getFechaDesde());
			cstmt.setString(i++, buscaOT.getFechaHasta());
			cstmt.setString(i++, buscaOT.getMatricula());	
			cstmt.setInt(i++, buscaOT.getIdTipoServicio());
			cstmt.setString(i++, buscaOT.getRut());					
			cstmt.setInt(i++, buscaOT.getEstado());
			rset = cstmt.executeQuery();
			
			while (rset.next()) {
				
				OrdenTrabajoDTO OTEncontrada = new OrdenTrabajoDTO();
				OTEncontrada.setIdUsuario(rset.getInt("idUsuario"));
				OTEncontrada.setIdOrdenDeTrabajo(rset.getInt("idOrdenDeTrabajo"));
				OTEncontrada.setMatricula(rset.getString("matricula"));				
				OTEncontrada.setFechaIngreso(rset.getString("fechaIngreso"));
				OTEncontrada.setFechaEntrega(rset.getString("fechaEntrega"));
				OTEncontrada.setIdTipoServicio(rset.getInt("idTipoServicio"));
				OTEncontrada.setPrecioTotal(rset.getInt("precioTotal"));
				//OTEncontrada.setEstado(rset.getInt("estado"));
				if(rset.getInt("estadoOT") == 0 ){OTEncontrada.setNombreEstado("Pendiente");}
				if(rset.getInt("estadoOT") == 1 ){OTEncontrada.setNombreEstado("En Taller");}
				if(rset.getInt("estadoOT") == 2 ){OTEncontrada.setNombreEstado("Terminada");}
				if(rset.getInt("estadoOT") == 3 ){OTEncontrada.setNombreEstado("Anulada");}
				
				OTEncontrada.setRut(rset.getString("rut"));
				

				listaResultadoBusquedaOT.add(OTEncontrada);
			}
			cstmt.close();

		} catch (SQLException ex) {

			throw new RuntimeException("error en buscar OT en busquedad.", ex);

		} finally {

			try {
				conexion.close();

			} catch (Exception ex) {

			}
			try {
				conexion.close();

			} catch (Exception ex) {
			}
		}

		return listaResultadoBusquedaOT;

	}
	
	
	// ////////////////////////////////////////////////////////////////////////////////////////////////////////
		public List<ItemOrdenTrabajoDTO> listaDeItemsPorOT(int idOrdenTrabajo) {

			ResultSet rset = null;
			
			List<ItemOrdenTrabajoDTO> listaItemsOT = new ArrayList<ItemOrdenTrabajoDTO>();

			try {

				CallableStatement cstmt = conexion
						.prepareCall("{ call paConRefaxionOrdenTrabajoListarRespuestosAsociados(?)}");

				int i = 1;
				cstmt.setInt(i++, idOrdenTrabajo);
				rset = cstmt.executeQuery();
				
				while (rset.next()) {
					
					ItemOrdenTrabajoDTO itemOTRep = new ItemOrdenTrabajoDTO();
					itemOTRep.setIdItem(rset.getInt("idRepuesto"));
					itemOTRep.setTipoItem("Respuesto");
					itemOTRep.setDescripcionItem(rset.getString("nombreRepuesto"));
					itemOTRep.setCantidadItem(rset.getInt("cantidad"));
					itemOTRep.setPrecioUnitarioItem(rset.getInt("precioRepuesto"));
					itemOTRep.setPrecioTotalItem(rset.getInt("precioRepuesto") * rset.getInt("cantidad"));
					listaItemsOT.add(itemOTRep);
					
				}
				cstmt.close();
				
				//////////////////////////////////////////////////servicios
				
				CallableStatement cstmt1 = conexion
						.prepareCall("{ call paConRefaxionOrdenTrabajoListarServiciosAsociados(?)}");

				int j = 1;
				cstmt1.setInt(j++, idOrdenTrabajo);
				rset = cstmt1.executeQuery();
				
				while (rset.next()) {
					
					ItemOrdenTrabajoDTO itemOTSer = new ItemOrdenTrabajoDTO();
					itemOTSer.setIdItem(rset.getInt("idServicio"));
					itemOTSer.setTipoItem("Servicio");
					itemOTSer.setDescripcionItem(rset.getString("servicioDescripcion"));
					itemOTSer.setCantidadItem(1);
					itemOTSer.setPrecioUnitarioItem(rset.getInt("precioListaServicio"));
					itemOTSer.setPrecioTotalItem(rset.getInt("precioListaServicio"));
					listaItemsOT.add(itemOTSer);
					
				}
				cstmt1.close();
				
		//////////////////////////////////////////////////paquetes
									
				CallableStatement cstmt2 = conexion
				.prepareCall("{ call paConRefaxionOrdenTrabajoListarPaquetesAsociados(?)}");
					
				int k = 1;
				cstmt2.setInt(k++, idOrdenTrabajo);
				rset = cstmt2.executeQuery();
					
				while (rset.next()) {
					
					ItemOrdenTrabajoDTO itemOTPaq = new ItemOrdenTrabajoDTO();
					itemOTPaq.setIdItem(rset.getInt("idPaqueteMantencion"));
					itemOTPaq.setTipoItem("Paq. Mantencion");
					itemOTPaq.setDescripcionItem(rset.getString("nombrePaqueteMantencion"));
					itemOTPaq.setCantidadItem(1);
					itemOTPaq.setPrecioUnitarioItem(rset.getInt("precioTotal"));
					itemOTPaq.setPrecioTotalItem(rset.getInt("precioTotal"));
					listaItemsOT.add(itemOTPaq);
					
				}
				cstmt2.close();

			} catch (SQLException ex) {

				throw new RuntimeException("error listar itemes de Orden de Trabajo.", ex);

			} finally {

				try {
					conexion.close();

				} catch (Exception ex) {

				}
				try {
					conexion.close();

				} catch (Exception ex) {
				}

			}

			return listaItemsOT;

		}

		// //////////////////////////////////////////////////////////////////////////////////////////////////
	
	public OrdenTrabajoDAO() {

	}

	public Connection getConexion() {
		return conexion;
	}

	public void setConexion(Connection conexion) {
		this.conexion = conexion;
	}

}
